package com.cxx.home.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cxx.common.dto.StatsChartDto;
import com.cxx.home.dto.bill.BillCategoryDto;
import com.cxx.home.dto.bill.BillItemDto;
import com.cxx.home.dto.bill.BillRecordDto;
import com.cxx.home.dto.bill.BillSummaryDto;
import com.cxx.home.entity.*;
import com.cxx.home.mapper.*;
import com.cxx.framework.web.CustomException;
import com.cxx.home.dao.BillDao;
import com.cxx.home.service.BillRecordService;
import com.cxx.home.vo.BillQueryVo;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

@Service
public class BillRecordServiceImpl implements BillRecordService {
    @Resource
    private BillDao billDao;

    @Resource
    private BillRecordMapper billRecordMapper;

    @Resource
    private BillPayMapper billPayMapper;

    @Resource
    private BillBookMapper billBookMapper;

    @Resource
    private BillCategoryMapper billCategoryMapper;

    @Resource
    private BillImageMapper billImageMapper;

    @Override
    public Boolean saveOrUpdateBillRecord(Long id, BillRecordDto billRecord) {
        // 1. 如果是更新 查询账单是否存在
        boolean isUpdate = id > 0;
        if (isUpdate && Objects.isNull(billRecordMapper.selectById(id))) {
            throw new CustomException("该账单不存在");
        }

        // 2. 新增/更新账单
        BillRecord newBillRecord = new BillRecord();
        BeanUtils.copyProperties(billRecord, newBillRecord);
        newBillRecord.setPayId(getBillPayId(billRecord.getPayAccount()));
        newBillRecord.setBookId(getBillBook(billRecord.getBookName()));
        newBillRecord.setCategoryId(getBillCategory(billRecord.getCategory()));

        if (isUpdate) {
            newBillRecord.setId(id);
            billRecordMapper.updateById(newBillRecord);
        } else {
            billRecordMapper.insert(newBillRecord);
        }

        // 6. 新增/更新账单图片
        if (isUpdate) {
            // 如果是更新先删除所有的账单图片记录
            deleteBillImage(id);
        }

        // 新增账单图片
        insertBillImage(newBillRecord.getId(), billRecord.getImageList());

        return Boolean.TRUE;
    }

    private Long getBillPayId(String payAccount) {
        LambdaQueryWrapper<BillPay> queryWrapper = Wrappers.lambdaQuery(BillPay.class);
        BillPay billPay = billPayMapper.selectOne(queryWrapper.eq(BillPay::getName, payAccount));
        if (Objects.isNull(billPay)) {
            throw new CustomException("暂无该账户类型");
        }

        return billPay.getId();
    }

    private Long getBillBook(String bookName) {
        LambdaQueryWrapper<BillBook> queryWrapper = Wrappers.lambdaQuery(BillBook.class);
        BillBook billBook = billBookMapper.selectOne(queryWrapper.eq(BillBook::getName, bookName));
        if (Objects.isNull(billBook)) {
            throw new CustomException("暂无该账本类型");
        }

        return billBook.getId();
    }

    private Long getBillCategory(String categoryName) {
        LambdaQueryWrapper<BillCategory> queryWrapper = Wrappers.lambdaQuery(BillCategory.class);
        BillCategory billCategory = billCategoryMapper.selectOne(queryWrapper.eq(BillCategory::getName, categoryName));
        if (Objects.isNull(billCategory)) {
            throw new CustomException("暂无该账单类型");
        }

        return billCategory.getId();
    }

    private void insertBillImage(Long billId, List<String> imageDtoList) {
        if (imageDtoList.isEmpty()) {
            return;
        }
        billDao.insertBillImage(billId, imageDtoList);
    }

    private void deleteBillImage(Long id) {
        billImageMapper.delete(Wrappers.lambdaQuery(BillImage.class).eq(BillImage::getBillId, id));
    }

    @Override
    public Boolean deleteBillRecord(Long id) {
        deleteBillImage(id);
        return billRecordMapper.deleteById(id) == 1;
    }

    @Override
    public BillRecordDto queryBillRecord(Long id) {
        return billDao.queryBillRecord(id);
    }

    @Override
    public List<BillSummaryDto> queryBillSummary(BillQueryVo billQuery) {
        return billDao.queryBillSummary(billQuery);
    }

    @Override
    public List<StatsChartDto> queryBillStats(String type, BillQueryVo billQuery) {
        return billDao.queryBillStats(type, billQuery);
    }

    @Override
    public List<BillItemDto> queryBillPay() {
        return billDao.queryBillPay();
    }

    @Override
    public List<BillItemDto> queryBillBook() {
        return billDao.queryBillBook();
    }

    @Override
    public List<BillCategoryDto> queryBillCategory() {
        return billDao.queryBillCategory();
    }
}
